package control.profiler;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class Profiler {
  private static Profiler instance;
  private ThreadLocal<Stack<Long>> startTimes;
  private Map<String, Statistics> statistics;
  private String indentation = "";
  
  private Profiler(){
    startTimes = new ThreadLocal<Stack<Long>>();
    statistics = new HashMap<String, Statistics>();
  }
  
  public static Profiler getInstance(){
    if(instance == null){
      instance = new Profiler();
    }
    return instance;
  }
  
  public void record(String details){
    getStartTimesStack().add(System.currentTimeMillis());
    if(details != null)
      putMessage(details);
    if(Thread.currentThread().getId() == 1)
      indentation += "  ";
  }
  
  private Stack<Long> getStartTimesStack(){
    if(startTimes.get() == null){
      startTimes.set(new Stack<Long>());
    }
    return startTimes.get();
  }
 
  public void display(){
    display("Done in ");
  }
  
  public void display(String message){
    if(Thread.currentThread().getId() == 1)
      indentation = indentation.substring(2);    
    double millis = System.currentTimeMillis() - getStartTimesStack().pop();
    putMessage(message + millis + "ms");
  }
  
  public void addStatistics(String statisticsName){
    if(Thread.currentThread().getId() == 1)
      indentation = indentation.substring(2);
    double millis = System.currentTimeMillis() - getStartTimesStack().pop();
    
    if(statistics.get(statisticsName) == null){
      statistics.put(statisticsName, new Statistics());
    }
    statistics.get(statisticsName).addValue(millis);
  }
  
  public Statistics getStatistics(String statisticsName){
    return statistics.get(statisticsName);
  }
  
  public void putMessage(String message){
    System.out.println(indentation + message);
  }
}
